/* 
** (Copyright) sejishikong <sejishikong@263.net>
** Authors:    sejishikong <sejishikong@263.net>
**             Wei Lian <lianwei2003.student@sina.com> 
** Maintainer: Wei Lian
**    This program is free software; you can redistribute it and/or modify
**    it under the terms of the GNU General Public License Version 2 as
**    published by the Free Software Foundation;
**
**    This program is distributed in the hope that it will be useful,
**    but WITHOUT ANY WARRANTY; without even the implied warranty of
**    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
**    GNU General Public License for more details.
**
**    You should have received a copy of the GNU General Public License
**    along with this program; if not, write to the Free Software
**    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
**
*/
#include "header.h"
#include "channel.h"
#include "mainwindow.h"
#include "mylistitem.h"
#include "config.h"
#include "mystatusbar.h"
#include "mylabel.h"
#include "menubar.h"

Channel::Channel(QWidget * parent, const char *name,
		 WFlags f):QListView(parent, name, f),
mainwindow(static_cast < Sopcast * >(parent))
{
    fetchingchannel = FALSE;
    bufchannel = new QBuffer();
    http = new QHttp(this);
    connect(http, SIGNAL(done(bool)), SLOT(httpdone(bool)));

    //listview
    addColumn(tr("Name"));
/*  addColumn(tr("Status"));
    addColumn(tr("Type"));
    addColumn(tr("Kbps"));
    addColumn(tr("Users"));
    addColumn(tr("Vists"));
    addColumn(tr("QualityS"));
    addColumn(tr("QualityC"));
    addColumn(tr("StarFrom"));
    addColumn(tr("URL"));
    addColumn(tr("Description"));*/
    setRootIsDecorated(TRUE);

    connect(this, SIGNAL(doubleClicked(QListViewItem *)), mainwindow,
	    SLOT(onlistitemclicked(QListViewItem *)));
    connect(this, SIGNAL(returnPressed(QListViewItem *)), mainwindow,
	    SLOT(onlistitemclicked(QListViewItem *)));
    connect(this,
	    SIGNAL(rightButtonClicked
		   (QListViewItem *, const QPoint &, int)), this,
	    SLOT(onrightbuttonclicked
		 (QListViewItem *, const QPoint &, int)));
    connect(this, SIGNAL(onItem(QListViewItem *)), this,
	    SLOT(onmousemoved(QListViewItem *)));

    //popup
    popup = new MyLabel(this);

}

Channel::~Channel()
{
    delete bufchannel;
}

void
 Channel::fetchchannel()
{
    if (fetchingchannel == FALSE) {
	fetchingchannel = TRUE;
	mainwindow->buttonchannel->setOn(TRUE);
	if (!bufchannel->open(IO_ReadWrite)) {
	    fprintf(stderr, "cannot create the buffer\n");
	    return;
	}

	QString str = mainwindow->vboxconfig->editchannelurl->text();
	http->setHost(str.section("/", 2, 2));	//"www.sopcast.org");
	http->get("/" + str.section("/", 3), bufchannel);	//"/channel/index.php", bufchannel);
    } else {
	if (!mainwindow->buttonchannel->isOn())
	    mainwindow->buttonchannel->setOn(TRUE);
    }
}

void Channel::httpdone(bool error)
{
    ///reset button state
    if (mainwindow->buttonchannel->isOn())
	mainwindow->buttonchannel->setOn(FALSE);
    fetchingchannel = FALSE;

    if (error) {
	mainwindow->statusbar->message("Error loading page", 3000);
	fprintf(stderr, "Error loading page!\n");
	bufchannel->close();
	return;
    }
    ///toggle channel sorting
    toggleChannelSort();
    ///

    bufchannel->reset();
    QDomDocument doc("mydocument");
    doc.setContent(bufchannel);
    bufchannel->close();

    QDomElement root = doc.documentElement();
    QDomNode node = root.firstChild();

    QDomNode channelnode, namenode;
    QListViewItem *groupitem = 0;
    MyListItem *item = 0;

    mainwindow->updateopenstate();
    clear();

    for (int i = 0; i < N_COLUMNS; i++)
	Max[i] = 1;
    static const char node_name[][20] =
	{ "name", "status", "stream_type", "kbps", "user_count",
	"visit_count", "qs", "qc", "start_from", "sop_address",
	"description"
    };
    ///group
    while (!node.isNull()) {
	if (node.isElement() && node.nodeName() == "group") {
	    groupitem = new QListViewItem(this, groupitem);
	    groupitem->setText(0, node.firstChild().toText().nodeValue());
	    ///channel
	    channelnode = node.toElement().firstChild();
	    while (!channelnode.isNull()) {
		if (channelnode.isElement()
		    && channelnode.nodeName() == "channel") {
		    ///element
		    item = new MyListItem(groupitem, item);
		    namenode = channelnode.toElement().firstChild();
		    while (!namenode.isNull()) {
			for (int i = 0; i < N_COLUMNS; i++) {
			    if (namenode.nodeName() == "sop_address")
				item->setText(URL_COLUMN,
					      namenode.firstChild().
					      toElement().firstChild().
					      toText().nodeValue());
			    else if (namenode.nodeName() == node_name[i])
				item->setText(i,
					      namenode.firstChild().
					      toText().nodeValue());
			}
			namenode = namenode.nextSibling();
		    }

		    ///filtering out channel
		    if (channelnode.
			toElement().attribute("type").toInt() == 1)
			item->state |= 2;
		    ///disable null channel
		    else if (item->text(URL_COLUMN) == "null")
			item->state |= 1;
		    else {
			static const int num[] =
			    { USER_COLUMN, VISIT_COLUMN, QS_COLUMN,
			    QC_COLUMN, KBPS_COLUMN
			};
			for (int i = 0; i < 5; i++)
			    Max[num[i]] =
				item->text(num[i]).toInt() >
				Max[num[i]] ? item->text(num[i]).
				toInt() : Max[num[i]];

		    }
		}
		channelnode = channelnode.nextSibling();
	    }
	    ///group
	}
	node = node.nextSibling();
    }

    ///toggle null channel
    toggleNullChannel();

    ////switch color
    switchChannelColor(mainwindow->menubar->color_column);

    ///set open
    QListViewItem *group = firstChild();
    int count = 0;
    while (group) {
	if (mainwindow->stateopen[count++] == 1)
	    group->setOpen(TRUE);
	group = group->nextSibling();
    }

}

void Channel::
onrightbuttonclicked(QListViewItem * item, const QPoint & pos, int)
{
    if (item)
	if (item->depth() == 1) {
	    popup->move(pos);
	    popup->
		setText
		("<table border=0 cellspacing=0 cellpadding=0><tr><td>" +
		 item->text(NAME_COLUMN) +
		 "</td></tr></table><hr>"
		 "<table border=0 cellspacing=0 cellpadding=0>"
		 "<tr><td>Users: " + item->text(USER_COLUMN) +
		 "</td><td>Visitors: " + item->text(VISIT_COLUMN) +
		 "</td></tr>" "<tr><td>QualityC: " +
		 item->text(QC_COLUMN) + "</td><td>QualityS: " +
		 item->text(6) + "</td></tr>" "<tr><td>MediaType: " +
		 item->text(STREAM_COLUMN) + "</td><td>KBps: " +
		 item->text(KBPS_COLUMN) +
		 "</td></tr>" "<tr><td>StartFrom: " +
		 item->text(START_COLUMN) + "</td></tr></table><br>" +
		 item->text(DESCRIPTION_COLUMN));
	    popup->adjustSize();
	    popup->show();
	}
}

void Channel::onmousemoved(QListViewItem *)
{
    popup->hide();
}


void Channel::mouseMoveEvent(QMouseEvent * e)
{
    QPoint p(e->pos());
    QRect pr(rect());
    pr.setWidth(pr.width() - verticalScrollBar()->width());
    pr.setHeight(pr.height() - horizontalScrollBar()->height());
    if (!pr.contains(p)) {
	popup->hide();
    }
}


void Channel::toggleChannelSort()
{
    if (!mainwindow->menubar->menu_config->isItemChecked(CHANNEL_SORT))
	setSortColumn(-1);
    else
	setSortColumn(0);
}


void Channel::toggleNullChannel()
{
    bool t = mainwindow->menubar->menu_config->isItemChecked(NULL_CHANNEL);

    QListViewItem *group = firstChild();
    while (group) {
	QListViewItem *child = group->firstChild();
	int count = 0;
	while (child) {
	    switch (((MyListItem *) child)->state) {
	    case 0:
		count++;
		break;
	    case 1:
		child->setEnabled(FALSE);
		if (t) {
		    child->setVisible(TRUE);
		    count++;
		} else
		    child->setVisible(FALSE);
		break;
	    case 2:
	    case 3:
		child->setEnabled(FALSE);
		child->setVisible(FALSE);
	    }
	    child = child->nextSibling();
	}
	if (count == 0)
	    group->setVisible(FALSE);
	else
	    group->setVisible(TRUE);
	///iterate to next group
	group = group->nextSibling();
    }
}


void Channel::switchChannelColor(int column)
{
    QListViewItem *group = firstChild();
    while (group) {
	QListViewItem *child = group->firstChild();
	while (child) {
	    if (child->isEnabled()) {
		int level =
		    int (child->text(column).toInt() *
			 (255. / Max[column]));

		level = level < 0 ? 0 : level;
		level = level > 255 ? 255 : level;

		((MyListItem *) child)->fcolor.setHsv(255 - level, 255,
						      125);
		child->repaint();
	    }
	    child = child->nextSibling();
	}
	group = group->nextSibling();
    }
}
